package com.xiaoyy.core.oplog.config.aspect;

import com.xiaoyy.core.common.enums.BoolEnum;
import com.xiaoyy.core.common.vo.BasePageVO;
import com.xiaoyy.core.common.vo.BaseVO;
import com.xiaoyy.core.common.vo.OplogVO;
import com.xiaoyy.core.config.annotations.SaveOplog;
import com.xiaoyy.core.common.exception.AppException;

import com.xiaoyy.core.oplog.dao.model.Oplog;
import com.xiaoyy.core.oplog.integration.OplogIntegration;
import com.xiaoyy.core.oplog.service.OplogService;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;

/***
 *日志处理切面
 * chenzh
 * 2020-01-15
 * */
@Aspect
@Component
@ConditionalOnExpression("${system.config.saveOplog}")
public class OplogAspect {
    private static final Logger logger = LoggerFactory.getLogger(OplogAspect.class);

    @Autowired
    OplogIntegration oplogIntegration;
    @Autowired
    OplogService oplogService;

    @Before("execution(* com.xiaoyy..*.integration..*.*(..))&&@annotation(saveOplog)")
    public void before(JoinPoint joinPoint, SaveOplog saveOplog) {
        //logger.info("=========================================用户业务操作日志开始执行......=========================================");
        //业务类型
        String operationType = saveOplog.operationType();
        //业务名称
        String operationName = saveOplog.operationName();
        //数据类型id使用字段
        String dataField = saveOplog.dataType();

        if ("other".equals(dataField)||"batch".equals(dataField)){
            dataField = "";
        }
        Object[] args = joinPoint.getArgs();
        if (args != null && args.length > 0) {
            Object argument = args[0];
            if (!(argument instanceof BaseVO)&&!(argument instanceof BasePageVO)){
                throw new AppException("业务日志保存传入第一个参数必须继承BaseVO或者BasePageVO");
            }
            OplogVO oplogVO = new OplogVO();
            oplogVO.setBatchFlag(BoolEnum.FALSE.getType());
            if ("batch".equals(dataField)){
                oplogVO.setBatchFlag(BoolEnum.TRUE.getType());
            }
            oplogVO.setOperationType(operationType);
            oplogVO.setOperationName(operationName);
            oplogVO.setDataType(dataField);
            oplogIntegration.saveOpLog(oplogVO,argument);
        }else{
            throw new AppException("操作日志必须传入继承BaseReq的请求实体类");
        }

    }
    @After("execution(* com.xiaoyy..*.integration..*.*(..))&&@annotation(saveOplog)")
    public void after(JoinPoint joinPoint, SaveOplog saveOplog) {
        //数据类型
        String dataType = saveOplog.dataType();
        //数据类型id使用字段
        String dataField = saveOplog.dataType();
        if ("other".equals(dataField)||"batch".equals(dataField)){
            return;
        }
        Object[] args = joinPoint.getArgs();
        if (args != null && args.length > 0) {
            Object argument = args[0];
            if (!(argument instanceof BaseVO)&&!(argument instanceof BasePageVO)){
                throw new AppException("业务日志保存传入参数必须继承BaseVO或者BasePageVO");
            }
            BeanWrapper beanWrapper = new BeanWrapperImpl(argument);
            //oplogId
            Long oplogId = null;
            if (beanWrapper.isWritableProperty("opOplogId")){
                if (null!=beanWrapper.getPropertyValue("opOplogId")) {
                    if (StringUtils.isNotBlank(beanWrapper.getPropertyValue("opOplogId").toString())){
                        oplogId =Long.parseLong(beanWrapper.getPropertyValue("opOplogId").toString());
                    }
                }
            }
            if (oplogId==null){
                return;
            }
            Oplog oplog = oplogService.getById(oplogId);
            if (oplog ==null){
                return;
            }
            if (StringUtils.isNotBlank(oplog.getDataId())){
                return;
            }
            if (StringUtils.isNotEmpty(dataField)){
                if (beanWrapper.isWritableProperty(dataField)){
                    if (beanWrapper.getPropertyValue(dataField)!=null) {
                        oplog.setDataId(beanWrapper.getPropertyValue(dataField).toString());
                        oplogService.updateById(oplog);
                    }
                }
            }
        }else{
            throw new AppException("业务日志保存传入参数必须继承BaseVO或者BasePageVO");
        }
        //logger.info("=========================================用户操作日志结束执行......=========================================");
    }
}
